home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / BCCAPP.ARJ / LOWLEVEL.C < prev    next >
C/C++ Source or Header  |  1991-09-15  |  9KB  |  411 lines

  1. /*
  2.  *
  3.  * Low-level systems routines used by Windows TOOLKIT
  4.  *
  5.  * (C) 1990 Vision Software
  6.  *
  7.  * $Id: lowlevel.c 1.2002 91/05/03 14:30:40 pcalvin beta Locker: pcalvin $
  8.  *
  9.  * Comments:
  10.  *
  11.  * This file consists of the DOS Kludge routines for Binary Screen IO.
  12.  * They are implemented (in general) using Borlands Text Library.
  13.  *
  14.  * Bugs:
  15.  *
  16.  * None documented.
  17.  *
  18.  */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <conio.h>
  22. #include <dos.h>
  23. #include <time.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <new.h>
  27.  
  28. #include <stdhdr.h>
  29. #include <adl.h>
  30.  
  31. #include "lowlevel.h"
  32.  
  33. /*
  34.  * Routines to create the "Shadow" for our windows etc..
  35.  */
  36. STATIC CONST CO coShadow = CoEgaFromCoCo(coDarkGray,coBlack);
  37. STATIC VOID ShadowRow(ROW row,COL col1,COL col2);
  38. STATIC VOID ShadowCol(COL col,ROW row1,ROW row2);
  39.  
  40. /*
  41.  *    Clears the screen.  If using NNANSI.SYS, this resets
  42.  *    the screen location
  43.  */
  44. STATIC VOID ClearScreen();
  45.  
  46. /*
  47.  * Fatal memory allocation handler..
  48.  */
  49. STATIC VOID FatalMemoryError();
  50.  
  51. /*
  52.  * Run-time dimensions for windows
  53.  */
  54. ROW rowGlobalWindowBottom;
  55. COL colGlobalWindowRight;
  56.  
  57. /*
  58.  * Static array for filling window using gettext/puttext.
  59.  * Large enough to hold entire screen..
  60.  */
  61. STATIC CCH cchWindowSize;
  62. STATIC UCHAR *rguchWindow;
  63.  
  64. /*
  65.  * No shadows in monochrome
  66.  */
  67. STATIC BOOL fShadows;
  68.  
  69. /*
  70.  * Generic Environment declarations.
  71.  * Allows automatically setting color
  72.  * mode.
  73.  */
  74. class ENV
  75.     {
  76. public:
  77.     ENV(VOID);
  78.     ~ENV(VOID);
  79. private:
  80.     CURSOR crs;
  81.     };
  82.  
  83. /*
  84.  * At startup, the cursor is visible.  Setting this
  85.  * static member to true ensures the cursor is turned
  86.  * back on after the program is complete..
  87.  */
  88. BOOL CURSOR::fCurrentState = fTrue;
  89. STATIC ENV env;
  90.  
  91. /*
  92.  * System initialization.  Turns off the startup cursor, determines
  93.  * the screen lines/max colours etc..
  94.  */
  95. ENV::ENV() : crs(fFalse)
  96.     {
  97.     text_info y;
  98.  
  99.     /* 
  100.      *    Initialize random number generator
  101.      */
  102.     randomize();
  103.     
  104.     /*
  105.      * Setup our new-handler..
  106.      */
  107.     set_new_handler(FatalMemoryError);
  108.  
  109.     /*
  110.      * Determine the startup screen conditions.
  111.      */
  112.     ClearScreen();
  113.     gettextinfo(&y);
  114.  
  115.     /*
  116.      * Only activate shadows if there is a colour screen..
  117.      */
  118.     if (y.currmode == C80 || y.currmode == C4350)
  119.         fShadows = fTrue;
  120.     else
  121.         fShadows = fFalse;
  122.  
  123.     /*
  124.      * Finally, initialize the rest of the system
  125.      */
  126.     rowGlobalWindowBottom = y.screenheight;
  127.     colGlobalWindowRight = y.screenwidth;
  128.  
  129.     cchWindowSize = rowGlobalWindowBottom * colGlobalWindowRight * 2;
  130.     rguchWindow = new UCHAR[cchWindowSize];
  131.     FillWindow(1,1,rowGlobalWindowBottom,colGlobalWindowRight,177,coLightBlue,coBlack);
  132.     /*
  133.      * Must be initialized here so it knows how many lines are available
  134.      */
  135.     HELP::Start();
  136.     }
  137.  
  138. /*
  139.  * Resets the system to the startup condition
  140.  */
  141. ENV::~ENV()
  142.     {
  143.     CursorColor(coWhite,coBlack);
  144.     window(1,1,colGlobalWindowRight,rowGlobalWindowBottom);
  145.     clrscr();
  146.     }
  147.  
  148. /*
  149.  *    Executes a dos command.  May be Nil, in which case
  150.  * we start a new command processor
  151.  */
  152. EXTERN VOID Command(SZ sz)
  153.     {
  154.     CURSOR crs(fTrue);                    // Most programs will not do this..
  155.     CHAR error;
  156.  
  157.     gettext(1,1,colGlobalWindowRight,rowGlobalWindowBottom,rguchWindow);
  158.     CursorColor(coWhite,coBlack);
  159.     window(1,1,colGlobalWindowRight,rowGlobalWindowBottom);
  160.     clrscr();
  161.  
  162.     /*
  163.       * Execute command/shell
  164.      */
  165.     if (sz == szNil || sz[0] == chNil)
  166.         system("");
  167.     else
  168.         system(sz);
  169.         
  170.     ClearScreen();
  171.     puttext(1,1,colGlobalWindowRight,rowGlobalWindowBottom,rguchWindow);
  172.     }
  173.     
  174. /*
  175.  *    Creates and executes a does shell
  176.  */
  177. EXTERN VOID DosShell()
  178.     {
  179.     if (FAskSz("Execute DOS sub-shell?","Press \"Y\" to spawn shell, \"N\" to abort"))
  180.         {
  181.         Command();
  182.         }
  183.     }
  184.  
  185. EXTERN VOID TerminateApplication()
  186.     {
  187.     if (FAskSz("Terminate Application?","Press \"Y\" to exit, \"N\" to return to application"))
  188.         {
  189.         exit(0);
  190.         }
  191.     }
  192.  
  193. /*
  194.  *    If using NNANSI.SYSs fast scroll option, this resets
  195.  *    the screen location
  196.  */
  197. STATIC VOID ClearScreen()
  198.     {
  199.     printf("\x1b" "[2J");
  200.     }
  201.     
  202. /*
  203.  * Set Cursor Color
  204.  */
  205. VOID CursorColor(CO coFore,CO coBack)
  206.     {
  207.     if (fShadows)
  208.         textattr(CoEgaFromCoCo(coFore,coBack));
  209.     else if (coBack == coGreen)
  210.         textattr(coReverse);
  211.     else
  212.         textattr(coNormal);
  213.     }
  214.  
  215. /*
  216.  * Moves the cursor unconditionally to row,col
  217.  */
  218. VOID SetGlobalRowCol(ROW row,COL col)
  219.     {
  220.     gotoxy(col,row);
  221.     }
  222.  
  223. /*
  224.  * Centers a string output at COL
  225.  */
  226. VOID DisplayCenter(ROW row,COL col,SZ sz,CO coFore,CO coBack)
  227.     {
  228.     Assert(sz != szNil);
  229.     Assert(row > rowNil && row <= rowGlobalWindowBottom);
  230.     Assert(col > colNil && col <= colGlobalWindowRight);
  231.  
  232.     DisplayString(row,col - (strlen(sz) >> 1),sz,coFore,coBack);
  233.     }
  234.  
  235. /*
  236.  * Displays a window border
  237.  */
  238. VOID DrawBorder(ROW row1,COL col1,ROW row2,COL col2,BD bd,CO coFore,CO coBack)
  239.     {
  240.     DisplayChar(row1,col1,(bd == bdDouble) ? 201 : 218,coFore,coBack);
  241.     FillRow(row1,col1+1,col2-1,(bd == bdDouble) ? 205 : 196,coFore,coBack);
  242.     DisplayChar(row1,col2,(bd == bdDouble) ? 187 : 191,coFore,coBack);
  243.     FillColumn(row1+1,col1,row2-1,(bd == bdDouble) ? 186 : 179,coFore,coBack);
  244.     FillColumn(row1+1,col2,row2-1,(bd == bdDouble) ? 186 : 179,coFore,coBack);
  245.     DisplayChar(row2,col1,(bd == bdDouble) ? 200 : 192,coFore,coBack);
  246.     FillRow(row2,col1+1,col2-1,(bd == bdDouble) ? 205 : 196,coFore,coBack);
  247.     DisplayChar(row2,col2,(bd == bdDouble) ? 188 : 217,coFore,coBack);
  248.     if (fShadows)
  249.         {
  250.         ShadowRow(row2+1,col1+1,col2+1);
  251.         ShadowCol(row1+1,col2+1,row2+1);
  252.         }
  253.     }
  254.  
  255. /*
  256.  * Turn on the shadow..
  257.  *    First thing to do is make sure the row to effect is entirely visable within
  258.  *    the screen.
  259.  */
  260. VOID ShadowRow(ROW row,COL colLeft,COL colRight)
  261.     {
  262.     if (row > rowGlobalWindowBottom)
  263.         return;
  264.     
  265.     colRight = Min(colRight,colGlobalWindowRight);
  266.     colLeft = Max(colLeft,1);
  267.  
  268.     CCH cchMax = (1+colRight - colLeft) << 1;
  269.     SZTEMP sz;
  270.  
  271.     gettext(colLeft,row,colRight,row,sz);
  272.  
  273.     for (CCH cch = 1;cch < cchMax;cch += 2)
  274.         sz[cch] = coShadow;
  275.  
  276.     puttext(colLeft,row,colRight,row,sz);
  277.     }
  278.  
  279. /*
  280.  * Shadow for the column
  281.  *    Again, the first thing here is to assert the column lies entirely within the
  282.  *    boundaries of the screen.
  283.  */
  284. VOID ShadowCol(ROW rowTop,COL col,ROW rowBottom)
  285.     {
  286.     if (col > colGlobalWindowRight)
  287.         return;
  288.     
  289.     rowBottom = Min(rowBottom,rowGlobalWindowBottom);
  290.     rowTop = Max(rowTop,1);
  291.  
  292.     CCH cchMax = (1+rowBottom - rowTop) << 1;
  293.     SZTEMP sz;
  294.  
  295.     gettext(col,rowTop,col,rowBottom,sz);
  296.  
  297.     for (CCH cch = 1;cch < cchMax;cch += 2)
  298.         sz[cch] = coShadow;
  299.  
  300.     puttext(col,rowTop,col,rowBottom,sz);
  301.     }
  302.  
  303. /*
  304.  * Display a single character
  305.  */
  306. VOID DisplayChar(ROW row,COL col,CHAR ch,CO coFore,CO coBack)
  307.     {
  308.     gotoxy(col,row);
  309.     CursorColor(coFore,coBack);
  310.     putch(ch);
  311.     }
  312.  
  313. /*
  314.  * Draw a null terminated string at row,col
  315.  */
  316. VOID DisplayString(ROW row,COL col,SZ sz,CO coFore,CO coBack)
  317.     {
  318.     Assert(sz != szNil);
  319.     Assert(row > rowNil && row <= rowGlobalWindowBottom);
  320.     Assert(col > colNil && col <= colGlobalWindowRight);
  321.  
  322.     CursorColor(coFore,coBack);
  323.     gotoxy(col,row);
  324.     while (*sz != chNil)
  325.         putch(*sz++);
  326.     }
  327.  
  328. /*
  329.  * Null terminated "HotString"  the cch'th character is highlighted..
  330.  */
  331. VOID HotString(ROW row,COL col,CCH cchHotKey,SZ sz,CO coFore,CO coBack)
  332.     {
  333.     Assert(sz != szNil);
  334.     Assert(row > rowNil && row <= rowGlobalWindowBottom);
  335.     Assert(col > colNil && col <= colGlobalWindowRight);
  336.  
  337.     DisplayString(row,col,sz,coFore,coBack);
  338.     DisplayChar(row,col+cchHotKey,sz[cchHotKey],coBlue,coBack);
  339.     }
  340.  
  341. /*
  342.  * Clears/Fills a window with this colour
  343.  */
  344. VOID FillWindow(ROW row1,COL col1,ROW row2,COL col2,CHAR ch,CO coFore,CO coBack)
  345.     {
  346.     CCH cchMax = (1+row2-row1) * (1+col2-col1) * 2;
  347.     CO coEga = CoEgaFromCoCo(coFore,coBack);
  348.     CO coMono = (coBack == coGreen) ? coReverse : coNormal;
  349.     CO co =  (fShadows) ? coEga : coMono;
  350.  
  351.     gettext(col1,row1,col2,row2,rguchWindow);
  352.  
  353.     for (CCH cch = cchNil; cch < cchMax; cch += 2)
  354.         {
  355.         rguchWindow[cch] = ch;
  356.         rguchWindow[cch+1] = co;
  357.         }
  358.  
  359.     puttext(col1,row1,col2,row2,rguchWindow);
  360.     }
  361.  
  362. /*
  363.  * Binary Keyboard input.  DOS KLUDGE:  getch() answers Nil if the key
  364.  * was a control (Ex. F1) the next answer is that key..
  365.  */
  366. CD CdInput(VOID)
  367.     {
  368.     REGISTER CD cd = getch();
  369.  
  370.     /*
  371.      *    Some keys require use to wait for the second answer..
  372.      */
  373.     if (cd == cdNil)
  374.         cd = getch() << 8;
  375.  
  376.     return (cd);
  377.     }
  378.  
  379. /*
  380.  * Implementation for cursor visibility control.  Resets cursor to
  381.  * previous visibilty upon destruction.
  382.  */
  383. CURSOR::CURSOR(BOOL fShow)
  384.     {
  385.     /*
  386.      * Save the state to be restored after this object goes out of scope
  387.      */
  388.     fFinishState = fCurrentState;
  389.     fCurrentState = fShow;
  390.     Set(fShow);
  391.     }
  392.  
  393. CURSOR::~CURSOR()
  394.     {
  395.     fCurrentState = fFinishState;
  396.     Set(fFinishState);
  397.     }
  398.  
  399. VOID CURSOR::Set(BOOL fShow)
  400.     {
  401.     _setcursortype(fShow ? _SOLIDCURSOR : _NOCURSOR);
  402.     }
  403.  
  404. /*
  405.  * Fatal memory error..
  406.  */
  407. STATIC VOID FatalMemoryError()
  408.     {
  409.     exit(1);
  410.     }
  411.